home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / X-Ray / X-RayLib Source / X_RayLib.c
Encoding:
Text File  |  1999-06-08  |  24.4 KB  |  871 lines  |  [TEXT/CWIE]

  1. // Copyright (C) 1999 Eric Roccasecca.  All rights reserved.
  2.  
  3. #define WINDOWLIBCOMPILE
  4.  
  5. #include "X_Ray_Priv.h"
  6. #include "Layers.h"
  7.  
  8. // Internal Prototypes
  9. OSErr        X_RayLib_Init (CFragInitBlockPtr ibp);
  10. OSErr        X_Ray_RememberNewWindow (WindowPtr theWindow, long windowKind, RgnHandle transRgn, RGBColor *clearColor, WindowPtr behind);
  11. X_Ray_WindowHandle X_Ray_GetWindowRec (WindowPtr theWindow);
  12. OSErr        X_Ray_DisposeWindow (WindowPtr theWindow);
  13. void         X_Ray_PrepWindowForDisposal (WindowPtr theWindow);
  14. X_Ray_AppRecHandle X_Ray_GetCurrentAppRec (X_Ray_CommRec *commRecAccess);
  15. void        X_Ray_AddWindowAsTSMWindow (X_Ray_WindowHandle newWindow, WindowPtr behind, X_Ray_CommRec *commRecAccess);
  16. void        X_Ray_AddWindowAsAppWindow (X_Ray_WindowHandle newWindow, WindowPtr behind, X_Ray_CommRec *commRecAccess);
  17.  
  18.  
  19. #define DO_DEBUG
  20.  
  21. // Internal Intialization routine
  22. OSErr X_RayLib_Init (CFragInitBlockPtr ibp)
  23. {
  24.     return noErr;
  25. }
  26.  
  27.  
  28.  
  29. //--------------------------------------------
  30. //    TRANSPARENT WINDOW ROUTINES
  31. //--------------------------------------------
  32.  
  33. #pragma export on
  34. void IsXRayLibInstalled (void)
  35. {
  36.     // DO NOT EVER CALL THIS FUNCTION
  37.     // see X_Ray.h for more info
  38.     
  39.     SysBeep (1); // this is to be annoying so you you pay attention and do not call this function
  40. }
  41. #pragma export off
  42.  
  43.  
  44. #pragma export on
  45. OSErr InitTransparentWindows (void)
  46. {
  47.     X_Ray_AppRecHandle    curApp;
  48.     X_Ray_CommRec        *commRecAccess;
  49.     OSErr                err;
  50.     
  51.     err = Gestalt (kX_RayGestalt, (long*)&commRecAccess);
  52.     if (err)
  53.         return kX_RayExtensionNotFoundError;
  54.     
  55.     curApp = X_Ray_GetCurrentAppRec (commRecAccess);
  56.     if (curApp == nil)
  57.         return kX_RayAppNotInitializedCorrectlyError;
  58.     
  59.     return noErr;
  60. }
  61. #pragma export off
  62.  
  63.  
  64. // Makes a new transparent window
  65. #pragma export on
  66. WindowPtr NewTransparentWindow (void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short procID, WindowPtr behind, Boolean goAwayFlag, long refCon, RgnHandle transRgn, RGBColor *clearColor, OSErr *windowErr)
  67. {
  68.     WindowPtr    result;
  69.     long        windowKind = 0;
  70.     
  71.     windowKind |= kAppWindow;
  72.     if (clearColor)
  73.         windowKind |= kIsClear;
  74.     
  75.     result = NewCWindow (wStorage, boundsRect, title, false, procID, behind, goAwayFlag, refCon);
  76.     if (result)
  77.     {
  78.         *windowErr = X_Ray_RememberNewWindow (result, windowKind, transRgn, clearColor, behind);
  79.         if (visible)
  80.         {
  81.             ShowWindow (result);
  82.             PaintOne (result, ((WindowPeek)result)->strucRgn); // assures frame looks correct when intersecting other trans windows
  83.         }
  84.     }
  85.     else
  86.         *windowErr = memFullErr;
  87.     
  88.     return result;
  89. }
  90. #pragma export off
  91.  
  92.  
  93. // Gets a new transparent window from a resource file
  94. #pragma export on
  95. WindowPtr GetNewTransparentWindow (short windowID, void *wStorage, WindowPtr behind, RgnHandle transRgn, RGBColor *clearColor, OSErr *windowErr)
  96. {
  97.     WindowPtr    result;
  98.     long        windowKind = 0;
  99.     
  100.     windowKind |= kAppWindow;
  101.     if (clearColor)
  102.         windowKind |= kIsClear;
  103.     
  104.     result = GetNewCWindow (windowID, wStorage, behind);
  105.     if (result)    
  106.         *windowErr = X_Ray_RememberNewWindow (result, windowKind, transRgn, clearColor, behind);
  107.     else
  108.         *windowErr = memFullErr;
  109.     
  110.     return result;
  111. }
  112. #pragma export off
  113.  
  114.  
  115. // Makes a new transparent dialog window
  116. #pragma export on
  117. DialogPtr NewTransparentDialog (void *dStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short procID, WindowPtr behind, Boolean goAwayFlag, long refCon, Handle itmLstHndl, RgnHandle transRgn, RGBColor *clearColor, OSErr *windowErr)
  118. {
  119.     DialogPtr    result;
  120.     long        windowKind = 0;
  121.     
  122.     windowKind |= kAppDialog;
  123.     if (clearColor)
  124.         windowKind |= kIsClear;
  125.     
  126.     result = NewColorDialog (dStorage, boundsRect, title, false, procID, behind, goAwayFlag, refCon, itmLstHndl);
  127.     if (result)
  128.     {
  129.         *windowErr = X_Ray_RememberNewWindow (result, windowKind, transRgn, clearColor, behind);
  130.         if (visible)
  131.         {
  132.             ShowWindow (result);
  133.             PaintOne (result, ((WindowPeek)result)->strucRgn); // assures frame looks correct when intersecting other trans windows
  134.         }
  135.     }
  136.     else
  137.         *windowErr = memFullErr;
  138.     
  139.     return result;
  140. }
  141. #pragma export off
  142.  
  143.  
  144. // Gets a new transparent dialog window from a resource file
  145. #pragma export on
  146. DialogPtr GetNewTransparentDialog (short dialogID, void *dStorage, WindowPtr behind, RgnHandle transRgn, RGBColor *clearColor, OSErr *windowErr)
  147. {
  148.     DialogPtr    result;
  149.     long        windowKind = 0;
  150.     
  151.     windowKind |= kAppDialog;
  152.     if (clearColor)
  153.         windowKind |= kIsClear;
  154.     
  155.     result = GetNewDialog (dialogID, dStorage, behind);
  156.     if (result)
  157.         *windowErr = X_Ray_RememberNewWindow (result, windowKind, transRgn, clearColor, behind);
  158.     else
  159.         *windowErr = memFullErr;
  160.     
  161.     return result;
  162. }
  163. #pragma export off
  164.  
  165.  
  166. // Makes a new transparent TSM service window
  167. #pragma export on
  168. OSErr NewTransparentServiceWindow (void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short theProc, WindowPtr behind, Boolean goAwayFlag, ComponentInstance ts, WindowPtr *window, RgnHandle transRgn, RGBColor *clearColor)
  169. {
  170.     OSErr    windowErr;
  171.     long    windowKind = 0;
  172.         
  173.     windowKind |= kTSMWindow;
  174.     if (clearColor)
  175.         windowKind |= kIsClear;
  176.     if ((long)ts == kCurrentProcess) // if an application owns a TSM window
  177.         windowKind |= kAppWindow;
  178.     
  179.     windowErr = NewServiceWindow (wStorage, boundsRect, title, false, theProc, behind, goAwayFlag, ts, window);
  180.     if (!windowErr)
  181.     {
  182.         windowErr = X_Ray_RememberNewWindow (*window, windowKind, transRgn, clearColor, behind);
  183.         if (visible)
  184.         {
  185.             ShowWindow (*window);
  186.             PaintOne (*window, ((WindowPeek)*window)->strucRgn); // assures frame looks correct when intersecting other trans windows
  187.         }
  188.     }
  189.     
  190.     return windowErr;
  191. }
  192. #pragma export off
  193.  
  194.  
  195. // Makes an existing TSM service window transparent
  196. #pragma export on
  197. OSErr MakeServiceWindowTransparent (WindowPtr theWindow, Boolean visible, WindowPtr behind, ComponentInstance ts, RgnHandle transRgn, RGBColor *clearColor)
  198. {
  199.     OSErr    windowErr;
  200.     long    windowKind = 0;
  201.     
  202.     windowKind |= kTSMWindow;
  203.     if (clearColor)
  204.         windowKind |= kIsClear;
  205.     if ((long)ts == kCurrentProcess) // if an application owns a TSM window
  206.         windowKind |= kAppWindow;
  207.     
  208.     windowErr = X_Ray_RememberNewWindow (theWindow, windowKind, transRgn, clearColor, behind);
  209.     if (visible)
  210.     {
  211.         ShowWindow (theWindow);
  212.         PaintOne (theWindow, ((WindowPeek)theWindow)->strucRgn); // assures frame looks correct when intersecting other trans windows
  213.     }
  214.     
  215.     return windowErr;
  216. }
  217. #pragma export off
  218.  
  219.  
  220. // Behaves like CloseWindow for transparent windows
  221. #pragma export on
  222. void CloseTransparentWindow (WindowPtr theWindow)
  223. {
  224.     X_Ray_PrepWindowForDisposal (theWindow);
  225.     CloseWindow (theWindow);
  226.     X_Ray_DisposeWindow (theWindow);
  227. }
  228. #pragma export off
  229.  
  230.  
  231. // Behaves like DisposeWindow for transparent windows
  232. #pragma export on
  233. void DisposeTransparentWindow (WindowPtr theWindow)
  234. {
  235.     X_Ray_PrepWindowForDisposal (theWindow);
  236.     DisposeWindow (theWindow);
  237.     X_Ray_DisposeWindow (theWindow);
  238. }
  239. #pragma export off
  240.  
  241.  
  242. // Behaves like CloseServiceWindow for transparent TSM service windows
  243. #pragma export on
  244. OSErr CloseTransparentServiceWindow (WindowPtr theWindow)
  245. {
  246.     OSErr    err;
  247.     
  248.     X_Ray_PrepWindowForDisposal (theWindow);
  249.     err = CloseServiceWindow (theWindow);
  250.     err = X_Ray_DisposeWindow (theWindow);
  251.     
  252.     return err;
  253. }
  254. #pragma export off
  255.  
  256.  
  257. // Behaves like CloseDialog for transparent dialog windows
  258. #pragma export on
  259. void CloseTransparentDialog (DialogPtr theDialog)
  260. {
  261.     X_Ray_PrepWindowForDisposal (theDialog);
  262.     CloseDialog (theDialog);
  263.     X_Ray_DisposeWindow (theDialog);
  264. }
  265. #pragma export off
  266.  
  267.  
  268. // Behaves like DisposeDialog for transparent dialog windows
  269. #pragma export on
  270. void DisposeTransparentDialog (DialogPtr theDialog)
  271. {
  272.     X_Ray_PrepWindowForDisposal (theDialog);
  273.     DisposeDialog (theDialog);
  274.     X_Ray_DisposeWindow (theDialog);
  275. }
  276. #pragma export off
  277.  
  278.  
  279. //--------------------------------------------
  280. //    TRANSPARENT WINDOW UTILITY FUNCTIONS
  281. //--------------------------------------------
  282.  
  283.  
  284. // returns the content buffer of a transparent window
  285. #pragma export on
  286. GWorldPtr GetTransparentWindowContentGWorld (WindowPtr theWindow)
  287. {
  288.     X_Ray_WindowHandle        theTransWindow;
  289.     
  290.     theTransWindow = X_Ray_GetWindowRec (theWindow);
  291.     if (theTransWindow)
  292.         return (*theTransWindow)->contentBuffer;
  293.     else
  294.         return nil;
  295. }
  296. #pragma export off
  297.  
  298.  
  299. // forces update of a transparent window
  300. // used mainly after content has been updated after using GetTransparentWindowContentBuffer
  301. // This should not be used in response to update events because this routine will cause another update event to occur
  302. // ans seriaously affect the performance of yoru software, as well as look really bad.
  303. // if updateRgn is nil, enire window is updated
  304. // note, this works by triggering an internal transparent update event
  305. // and by invalidating the updateRgn passed to the function in theWindow
  306. // so your own event handler wiil eventually receive an updateEvent
  307.  
  308. // actually just copies the contentBuffer back into the window and
  309. // the X-Ray QuickDraw patches magically take care of the rest
  310. #pragma export on
  311. void UpdateTransparentWindow (WindowPtr theWindow, RgnHandle updateRgn)
  312. {
  313.     X_Ray_WindowHandle        clrWinRec;
  314.     GrafPtr                    curPort;
  315.     PixMapHandle            contPMap;
  316.     
  317.     clrWinRec = X_Ray_GetWindowRec (theWindow);
  318.     if (clrWinRec == nil)
  319.         return;
  320.     
  321.     GetPort (&curPort);
  322.     SetPort (theWindow);
  323.     
  324.     contPMap = GetGWorldPixMap ((*clrWinRec)->contentBuffer);
  325.     LockPixels (contPMap);
  326.     CopyBits ((BitMap*)*contPMap, &theWindow->portBits, &(*contPMap)->bounds, &theWindow->portRect, srcCopy, updateRgn);
  327.     UnlockPixels (contPMap);
  328.     
  329.     SetPort (curPort);
  330. }
  331. #pragma export off
  332.  
  333.  
  334. // Returns TRUE if window is a transparent window
  335. #pragma export on
  336. Boolean    IsWindowTransparent (WindowPtr theWindow)
  337. {
  338.     X_Ray_WindowHandle        trnWinRec;
  339.      
  340.     trnWinRec = X_Ray_GetWindowRec (theWindow);
  341.     if (trnWinRec == nil)
  342.         return false;
  343.     else
  344.         return true;
  345. }
  346. #pragma export off
  347.  
  348.  
  349. // sets a windows level of transparency
  350. #pragma export on
  351. void SetWindowTransparency (unsigned short transparency, WindowPtr theWindow)
  352. {
  353.     GDHandle                curGDH;
  354.     CGrafPtr                curGWorld;
  355.     X_Ray_WindowHandle        transWinRec;
  356.     RGBColor                transColor;
  357.     
  358.     transWinRec = X_Ray_GetWindowRec (theWindow);
  359.     if (!transWinRec)
  360.         return;
  361.     
  362.     GetGWorld (&curGWorld, &curGDH);
  363.     SetGWorld ((*transWinRec)->maskBuffer, nil);
  364.     
  365.     (*transWinRec)->transparency = transparency;
  366.     transColor.red = transColor.green = transColor.blue = transparency;
  367.     RGBForeColor (&transColor);
  368.     
  369.     LockPixels (GetGWorldPixMap((*transWinRec)->maskBuffer));
  370.     PaintRect (&(*transWinRec)->maskBuffer->portRect);
  371.     UnlockPixels (GetGWorldPixMap((*transWinRec)->maskBuffer));
  372.     
  373.     BackColor (whiteColor);
  374.     ForeColor (blackColor);
  375.     
  376.     SetGWorld (curGWorld, curGDH); // restore graphics environment
  377.     
  378.     UpdateTransparentWindow (theWindow, nil);
  379. }
  380. #pragma export off
  381.  
  382.  
  383. // retrives the transparency of a window
  384. // will return noErr if window was found to be transparent
  385. // *transparency is unchanged if it can not be retrieved
  386. #pragma export on
  387. OSErr GetWindowTransparency (unsigned short *transparency, WindowPtr theWindow)
  388. {
  389.     OSErr                    err = noErr;
  390.     X_Ray_WindowHandle        transWinRec;
  391.     
  392.     if (transparency)
  393.     {
  394.         transWinRec = X_Ray_GetWindowRec (theWindow);
  395.         if (!transWinRec)
  396.             return 1;
  397.         
  398.         *transparency = (*transWinRec)->transparency;
  399.     }
  400.     else
  401.         err = paramErr;
  402.     
  403.     return err;
  404. }
  405. #pragma export off
  406.  
  407.  
  408. // <<< PARTIALLY IMPLEMENTED >>>
  409. // Sets the clear color for a transparent window
  410. #pragma export on
  411. void SetTransparentWindowClearColor (WindowPtr theWindow, RGBColor *newClearColor)
  412. {
  413.     X_Ray_WindowHandle        clrWinRec;
  414.     
  415.     clrWinRec = X_Ray_GetWindowRec (theWindow);
  416.     if ((clrWinRec == nil) || (newClearColor == nil))
  417.         return;
  418.     
  419.     (*clrWinRec)->clearColor = *newClearColor;
  420.     (*clrWinRec)->windowKind |= kIsClear;
  421.     
  422.     // ADD
  423.     // force update of this window here
  424.     UpdateTransparentWindow (theWindow, nil);
  425. }
  426. #pragma export off
  427.  
  428.  
  429. // <<< PARTIALLY IMPLEMENTED >>>
  430. // Removes the clear color for a transparent window
  431. #pragma export on
  432. void RemoveTransparentWindowClearColor (WindowPtr theWindow)
  433. {
  434.     X_Ray_WindowHandle        clrWinRec;
  435.     
  436.     clrWinRec = X_Ray_GetWindowRec (theWindow);
  437.     if (clrWinRec == nil)
  438.         return;
  439.     
  440.     (*clrWinRec)->windowKind &= ~kIsClear;
  441.     (*clrWinRec)->clearColor.red = (*clrWinRec)->clearColor.green = (*clrWinRec)->clearColor.blue = 0xFFFF;  // white
  442.     
  443.     // ADD
  444.     // force update of this window
  445.     UpdateTransparentWindow (theWindow, nil);
  446. }
  447. #pragma export off
  448.  
  449.  
  450. // <<< PARTIALLY IMPLEMENTED >>>
  451. // limits area of window that is transparent
  452. // X_Ray QD patches do not currently recognize this feature although this routine can be called safely
  453. #pragma export on
  454. void SetTransparentWindowTransparentRegion (WindowPtr theWindow, RgnHandle transRgn)
  455. {
  456.     X_Ray_WindowHandle        transWinRec;
  457.     
  458.     transWinRec = X_Ray_GetWindowRec (theWindow);
  459.     if ((transWinRec == nil) || (transRgn == nil))
  460.         return;
  461.     
  462.     CopyRgn (transRgn, (*transWinRec)->transparentRgn);
  463.     
  464.     // ADD
  465.     // force update of this window
  466.     UpdateTransparentWindow (theWindow, nil);
  467. }
  468. #pragma export off
  469.  
  470.  
  471. // <<< PARTIALLY IMPLEMENTED >>>
  472. // removes limiting area of window that is transparent
  473. // X_Ray QD patches do not currently recognize this feature although this routine can be called safely
  474. #pragma export on
  475. void RemoveTransparentWindowTransparentRegion (WindowPtr theWindow)
  476. {
  477.     X_Ray_WindowHandle        transWinRec;
  478.     
  479.     transWinRec = X_Ray_GetWindowRec (theWindow);
  480.     if (transWinRec == nil)
  481.         return;
  482.     
  483.     SetEmptyRgn ((*transWinRec)->transparentRgn);
  484.     
  485.     // ADD
  486.     // force update of this window
  487.     UpdateTransparentWindow (theWindow, nil);
  488. }
  489. #pragma export off
  490.  
  491.  
  492. //--------------------------------------------
  493. //    INTERNAL X_RayLIB ROUTINES
  494. //--------------------------------------------
  495.  
  496.  
  497. // Allocates and initializes a new transparent window
  498. OSErr X_Ray_RememberNewWindow (WindowPtr theWindow, long windowKind, RgnHandle transRgn, RGBColor *clearColor, WindowPtr behind)
  499. {
  500.     X_Ray_WindowHandle        newWindow;
  501.     OSErr                    err;
  502.     X_Ray_CommRec            *commRecAccess;
  503.     THz                        curZone;
  504.     GDHandle                curGDH;
  505.     CGrafPtr                curGWorld;
  506.     RGBColor                transColor;
  507.     
  508.     err = Gestalt (kX_RayGestalt, (long*)&commRecAccess);
  509.     if (err)
  510.         return kX_RayExtensionNotFoundError;    
  511.     
  512.     newWindow = (X_Ray_WindowHandle)NewHandleSysClear (sizeof(X_Ray_Window));    // create new window record in system heap
  513.     if (newWindow)
  514.     {
  515.         curZone = GetZone ();
  516.         SetZone (SystemZone());        // all transparent window memory is allocated in the system heap
  517.         
  518.         HLock ((Handle)newWindow);
  519.         
  520.         (*newWindow)->theWindow = theWindow;
  521.         (*newWindow)->windowKind = windowKind;
  522.         transColor.red = transColor.green = transColor.blue = (*newWindow)->normalTransparency = (*newWindow)->transparency = kTransparencyNormal;
  523.         (*newWindow)->transparentUpdateRgn = NewRgn(); // default is empty region
  524.         (*newWindow)->transparentRgn = NewRgn(); // default is empty region
  525.         if (clearColor)
  526.             (*newWindow)->clearColor = *clearColor;
  527.         else
  528.             (*newWindow)->clearColor.red = (*newWindow)->clearColor.green = (*newWindow)->clearColor.blue = 0xFFFF;  // white
  529.         
  530.         // remember how window is owned
  531.         if (windowKind&kAppWindow)
  532.             (*newWindow)->owner = X_Ray_GetCurrentAppRec (commRecAccess);
  533.         else
  534.             (*newWindow)->owner = nil; // nil if window is TSM window and owned by an operating system process
  535.         
  536.         //set the WDEF
  537.         (*newWindow)->origWDEF = ((WindowPeek)theWindow)->windowDefProc;
  538.         ((WindowPeek)theWindow)->windowDefProc = (Handle)commRecAccess->wdefStub;
  539.         
  540.         // make the buffer areas
  541.         err = NewGWorld (&(*newWindow)->underBuffer, 32, &theWindow->portRect, nil, nil, 0);
  542.         if (err)
  543.             DebugNum (err);
  544.         err = NewGWorld (&(*newWindow)->contentBuffer, 32, &theWindow->portRect, nil, nil, 0);
  545.         if (err)
  546.             DebugNum (err);
  547.         err = NewGWorld (&(*newWindow)->mixBuffer, 32, &theWindow->portRect, nil, nil, 0);
  548.         if (err)
  549.             DebugNum (err);
  550.         err = NewGWorld (&(*newWindow)->maskBuffer, 32, &theWindow->portRect, nil, nil, 0);
  551.         if (err)
  552.             DebugNum (err);
  553.         // initialize the buffers
  554.         GetGWorld (&curGWorld, &curGDH);
  555.         
  556.         SetGWorld ((*newWindow)->underBuffer, nil);
  557.         ForeColor (blackColor);
  558.         BackColor (whiteColor);
  559.         LockPixels (GetGWorldPixMap((*newWindow)->underBuffer));
  560.         EraseRect (&(*newWindow)->underBuffer->portRect);
  561.         UnlockPixels (GetGWorldPixMap((*newWindow)->underBuffer));
  562.         
  563.         SetGWorld ((*newWindow)->contentBuffer, nil);
  564.         ForeColor (blackColor);
  565.         BackColor (whiteColor);
  566.         LockPixels (GetGWorldPixMap((*newWindow)->contentBuffer));
  567.         EraseRect (&(*newWindow)->contentBuffer->portRect);
  568.         UnlockPixels (GetGWorldPixMap((*newWindow)->contentBuffer));
  569.         
  570.         SetGWorld ((*newWindow)->mixBuffer, nil);
  571.         ForeColor (blackColor);
  572.         BackColor (whiteColor);
  573.         LockPixels (GetGWorldPixMap((*newWindow)->mixBuffer));
  574.         EraseRect (&(*newWindow)->mixBuffer->portRect);
  575.         UnlockPixels (GetGWorldPixMap((*newWindow)->mixBuffer));
  576.         
  577.         SetGWorld ((*newWindow)->maskBuffer, nil);
  578.         RGBForeColor (&transColor); // setup default transparency
  579.         LockPixels (GetGWorldPixMap((*newWindow)->maskBuffer));
  580.         PaintRect (&(*newWindow)->maskBuffer->portRect);
  581.         UnlockPixels (GetGWorldPixMap((*newWindow)->maskBuffer));
  582.         BackColor (whiteColor);
  583.         ForeColor (blackColor);
  584.         
  585.         SetGWorld (curGWorld, curGDH); // restore graphics environment
  586.         
  587.         if (windowKind&kTSMWindow)
  588.             X_Ray_AddWindowAsTSMWindow (newWindow, behind, commRecAccess);
  589.         else
  590.             X_Ray_AddWindowAsAppWindow (newWindow, behind, commRecAccess);
  591.         
  592.         HUnlock ((Handle)newWindow);
  593.         
  594.         SetZone (curZone);
  595.         
  596.         return noErr;
  597.     }
  598.     else
  599.         return memFullErr;
  600. }
  601.  
  602.  
  603. // adds a new transparent window to the transparent TSM window list in correct order
  604. void X_Ray_AddWindowAsTSMWindow (X_Ray_WindowHandle newWindow, WindowPtr behind, X_Ray_CommRec *commRecAccess)
  605. {
  606.     X_Ray_WindowHandle        curTransWindow = nil;
  607.     WindowPtr                curWindow = nil;
  608.     
  609.     GetFrontServiceWindow (&curWindow);
  610.     curTransWindow = commRecAccess->tsmWindowList;
  611.     
  612.     if ((behind == (WindowPtr)-1) || (curTransWindow == nil))  // window is in front of all others OR windowlist is empty
  613.     {
  614.         (*newWindow)->nextWindow = commRecAccess->tsmWindowList;
  615.         if (commRecAccess->tsmWindowList)
  616.             (*(commRecAccess->tsmWindowList))->previousWindow = newWindow;
  617.         
  618.         if (!(*newWindow)->nextWindow) // fix end of list record
  619.             commRecAccess->tsmLastWindow = newWindow;
  620.         
  621.         commRecAccess->tsmWindowList = newWindow;
  622.     }
  623.     else if (behind == nil) // window is behind all others
  624.     {
  625.         while ((*curTransWindow)->nextWindow)
  626.             curTransWindow = (*curTransWindow)->nextWindow;
  627.         (*newWindow)->previousWindow = curTransWindow;
  628.         (*curTransWindow)->nextWindow = newWindow;
  629.         commRecAccess->tsmLastWindow = newWindow;
  630.     }
  631.     else // window is in the middle of the list
  632.     {
  633.         while (curWindow)
  634.         {
  635.             X_Ray_WindowHandle    foundWindow;
  636.             
  637.             foundWindow = X_Ray_GetWindowRec (curWindow);
  638.             if (foundWindow)
  639.                 curTransWindow = foundWindow; // remember the last transparent window found in front to back order
  640.             if (curWindow == behind)
  641.             {
  642.                 (*newWindow)->nextWindow = (*curTransWindow)->nextWindow;
  643.                 (*newWindow)->previousWindow = curTransWindow;
  644.                 (*curTransWindow)->nextWindow = newWindow;
  645.                 if ((*newWindow)->nextWindow)
  646.                     (*((*newWindow)->nextWindow))->previousWindow = newWindow;
  647.                 if (!(*newWindow)->nextWindow) // fix end of list record
  648.                     commRecAccess->tsmLastWindow = newWindow;
  649.                 break;
  650.             }
  651.             else
  652.                 curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
  653.         }
  654.     }
  655. }
  656.  
  657.  
  658. // adds a new transparent window to current app's transparent window list
  659. void X_Ray_AddWindowAsAppWindow (X_Ray_WindowHandle newWindow, WindowPtr behind, X_Ray_CommRec *commRecAccess)
  660. {
  661.     X_Ray_WindowHandle        curTransWindow = nil;
  662.     WindowPtr                curWindow = nil;
  663.     X_Ray_AppRecHandle        curApp;
  664.     
  665.     curApp = X_Ray_GetCurrentAppRec (commRecAccess);
  666.     curWindow = GetFirstLayerWindow ((*curApp)->appGlobalWindow);    // get front of window list of current app
  667.     curTransWindow = (*curApp)->windowList; // get transparent window list of current app
  668.     
  669.     if ((behind == (WindowPtr)-1) || (curTransWindow == nil))  // window is in front of all others OR windowlist is empty
  670.     {
  671.         (*newWindow)->nextWindow = (*curApp)->windowList;
  672.         if ((*curApp)->windowList)
  673.             (*((*curApp)->windowList))->previousWindow = newWindow;
  674.         if (!(*newWindow)->nextWindow) // fix end of list record
  675.             (*curApp)->lastWindow = newWindow;
  676.         (*curApp)->windowList = newWindow;
  677.     }
  678.     else if (behind == nil) // window is behind all others
  679.     {
  680.         while ((*curTransWindow)->nextWindow)
  681.             curTransWindow = (*curTransWindow)->nextWindow;
  682.         (*newWindow)->previousWindow = curTransWindow;
  683.         (*curTransWindow)->nextWindow = newWindow;
  684.         (*curApp)->lastWindow = newWindow;
  685.     }
  686.     else // window is in the middle of the list
  687.     {
  688.         while (curWindow)
  689.         {
  690.             X_Ray_WindowHandle    foundWindow;
  691.             
  692.             foundWindow = X_Ray_GetWindowRec (curWindow);
  693.             if (foundWindow)
  694.                 curTransWindow = foundWindow;
  695.             if (curWindow == behind)
  696.             {
  697.                 (*newWindow)->nextWindow = (*curTransWindow)->nextWindow;
  698.                 (*newWindow)->previousWindow = curTransWindow;
  699.                 (*curTransWindow)->nextWindow = newWindow;
  700.                 if ((*newWindow)->nextWindow)
  701.                     (*((*newWindow)->nextWindow))->previousWindow = newWindow;
  702.                 if (!(*newWindow)->nextWindow) // fix end of list record
  703.                     (*curApp)->lastWindow = newWindow;
  704.                 break;
  705.             }
  706.             else
  707.                 curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
  708.         }
  709.     }    
  710. }
  711.  
  712.  
  713. // returns record of current application
  714. X_Ray_AppRecHandle X_Ray_GetCurrentAppRec (X_Ray_CommRec *commRecAccess)
  715. {
  716.     ProcessSerialNumber        curSerialNum;
  717.     X_Ray_AppRecHandle        curApp;
  718.     OSErr                    err;
  719.     Boolean                    sameProcess;
  720.     
  721.     err = GetCurrentProcess (&curSerialNum);
  722.     curApp = commRecAccess->appList;
  723.     while (curApp != nil)
  724.     {
  725.         HLock ((Handle)curApp);
  726.         err = SameProcess (&curSerialNum, &(*curApp)->appSerialNum, &sameProcess);
  727.         HUnlock ((Handle)curApp);
  728.         
  729.         if (sameProcess)
  730.             return curApp;
  731.         curApp = (*curApp)->nextApp;
  732.     }
  733.     
  734.     return nil;
  735. }
  736.  
  737.  
  738. //retrieves a X_Ray_WindowHandle corresponding to a WindowPtr
  739. X_Ray_WindowHandle X_Ray_GetWindowRec (WindowPtr theWindow)
  740. {
  741.     X_Ray_WindowHandle    curWindow;
  742.     OSErr                err;
  743.     X_Ray_CommRec        *commRecAccess;
  744.     Boolean                searchExhaustive = false;
  745.     X_Ray_AppRecHandle curApp;
  746.     
  747.     if (theWindow == nil)
  748.         return nil;
  749.     
  750.     err = Gestalt (kX_RayGestalt, (long*)&commRecAccess);
  751.     if (err)
  752.         return nil;
  753.     
  754.     curWindow = commRecAccess->tsmWindowList;
  755.     while (curWindow)
  756.     {
  757.         if ((*curWindow)->theWindow == theWindow)
  758.             return curWindow;
  759.         curWindow = (*curWindow)->nextWindow;
  760.     }
  761.     
  762.     curApp = commRecAccess->appList;
  763.     while (curApp)
  764.     {
  765.         curWindow = (*curApp)->windowList;
  766.         while (curWindow)
  767.         {
  768.             if ((*curWindow)->theWindow == theWindow)
  769.                 return curWindow;
  770.             curWindow = (*curWindow)->nextWindow;
  771.         }
  772.         curApp = (*curApp)->nextApp;
  773.     }
  774.     
  775.     return nil;
  776. }
  777.  
  778.  
  779. // Disposes of all memory allocated for a transparent window
  780. OSErr X_Ray_DisposeWindow (WindowPtr theWindow)
  781. {
  782.     X_Ray_WindowHandle        deadWin;
  783.     X_Ray_CommRec            *commRecAccess;
  784.     OSErr                    err;
  785.     
  786.     err = Gestalt (kX_RayGestalt, (long*)&commRecAccess);
  787.     if (err)
  788.         return kX_RayExtensionNotFoundError;
  789.     
  790.     deadWin = X_Ray_GetWindowRec (theWindow);
  791.     if (!deadWin)
  792.         return paramErr;
  793.     
  794.     HLock ((Handle)deadWin);
  795.     
  796.     // fix list head and tail if necessary
  797.     X_Ray_FixOwningListEnds (deadWin);
  798.     
  799.     // remove from window list
  800.     if ((*deadWin)->nextWindow)
  801.         (*((*deadWin)->nextWindow))->previousWindow = (*deadWin)->previousWindow;
  802.     if ((*deadWin)->previousWindow)
  803.         (*((*deadWin)->previousWindow))->nextWindow = (*deadWin)->nextWindow;
  804.     
  805.     // release allocated memory
  806.     DisposeGWorld ((*deadWin)->underBuffer);
  807.     DisposeGWorld ((*deadWin)->contentBuffer);
  808.     DisposeGWorld ((*deadWin)->mixBuffer);
  809.     DisposeGWorld ((*deadWin)->maskBuffer);
  810.     DisposeRgn ((*deadWin)->transparentUpdateRgn);
  811.     DisposeRgn ((*deadWin)->transparentRgn);
  812.     
  813.     HUnlock ((Handle)deadWin);
  814.     
  815.     DisposeHandle ((Handle)deadWin);
  816. }
  817.  
  818.  
  819. // fixes the list head and tail for the window if the window is the head or tail of the list
  820. void X_Ray_FixOwningListEnds (X_Ray_WindowHandle theWindow)
  821. {
  822.     X_Ray_CommRec    *commRecAccess;
  823.     OSErr            err;
  824.     
  825.     err = Gestalt (kX_RayGestalt, (long*)&commRecAccess);
  826.     if (err)
  827.         return;
  828.     
  829.     if (((*theWindow)->windowKind)&kTSMWindow)
  830.     {
  831.         if (theWindow == commRecAccess->tsmWindowList)
  832.             commRecAccess->tsmWindowList = (*theWindow)->nextWindow;
  833.         if (theWindow == commRecAccess->tsmLastWindow)
  834.             commRecAccess->tsmLastWindow = (*theWindow)->previousWindow;
  835.     }
  836.     else
  837.     {
  838.         if (theWindow == (*((*theWindow)->owner))->windowList)
  839.             (*((*theWindow)->owner))->windowList = (*theWindow)->nextWindow;
  840.         
  841.         if (theWindow == (*((*theWindow)->owner))->lastWindow)
  842.             (*((*theWindow)->owner))->lastWindow = (*theWindow)->previousWindow;
  843.     }
  844. }
  845.  
  846.  
  847. // sets windowKind to kWindowDisposed so other X_Ray QuickDraw routines will ignore window
  848. void X_Ray_PrepWindowForDisposal (WindowPtr theWindow)
  849. {
  850.     X_Ray_WindowHandle  soonToBeDeadWindow;
  851.     
  852.     soonToBeDeadWindow = X_Ray_GetWindowRec (theWindow);
  853.     if (soonToBeDeadWindow)
  854.     {
  855.         HideWindow (theWindow); // make the window "disappear" since it should no longer be graphically calculated
  856.         (*soonToBeDeadWindow)->windowKind |= kWindowDisposed;
  857.     }
  858. }
  859.  
  860.  
  861. #ifdef DO_DEBUG
  862. // shows a number in the debugger
  863. void DebugNum (long theNum)
  864. {
  865.     Str15    theNumStr;
  866.     
  867.     NumToString (theNum, theNumStr);
  868.     DebugStr (theNumStr);
  869. }
  870. #endif
  871.